package nl.infodation.emr.utility;

import java.util.List;

import net.atontech.vaadin.ui.numericfield.NumericField;
import nl.infodation.emr.pricingservice.controller.ListBoxDataController;
import nl.infodation.emr.pricingservice.data.ListBoxData;
import nl.infodation.emr.pricingservice.entity.DomainRule.PriceType;
import nl.infodation.emr.pricingservice.entity.SystemDetail;
import nl.infodation.emr.pricingservice.entity.SystemValue;
import nl.infodation.emr.pricingservice.entity.SystemValue.TableName;
import nl.infodation.emr.pricingservice.ui.component.ComponentFactory;
import nl.infodation.emr.pricingservice.ui.page.SessionData;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.Field;
import com.vaadin.ui.Label;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.Select;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;

/**
 * @author trule/Success
 * 
 */
 
public class CreateElementOnGui {
	private static final Logger LOG = LoggerFactory
			.getLogger(CreateElementOnGui.class);
	
	public enum StyleNameCss {
		INLINE_BOX(
				"inline_box"), INLINE_FILED("inline_field"), INLINE_BOX_CCD_REQUIRE(
				"inline_box cbb_require"), INLINE("inline"), INLINE_FILED_CCD_REQUIRE(
				"inline_field cbb_require"), SELECT_BOX("selectbox-style"),
				SMALL_BUTTON("small_button"), BUTTON_STYLE("button_style"),
				RIGHT_BUTTON("right_button");

		private String classCss;

		private StyleNameCss(final String styleName) {
			classCss = styleName;
		}

		public String getStyleName() {
			return classCss;
		}
	}

	static public void addLocation(AbstractComponent component, String styleName,
			CustomLayout customLayout, String position) {
		if (styleName != null) {
			component.setStyleName(styleName);
		}

		if (position != null) {
			customLayout.addComponent(component, position);
		}
	}
	
	/**
	 * Create text file set position on layout
	 * 
	 * @param nameCode
	 *            : is name of text field
	 * @param styleName
	 *            : is name class format css
	 * @param customLayout
	 *            : is name layout
	 * @param position
	 *            : is name position on layout
	 */
	static public TextField createTexboxPosition(String styleName,
			CustomLayout customLayout, String position) {
		TextField component = new TextField();
		component.setNullRepresentation("");
		addLocation(component, styleName, customLayout, position);
		return component;
	}

	/**
	 * Create lable file set position on layout
	 * 
	 * @param textField
	 *            : is name of lable
	 * @param styleName
	 *            : is name class format css
	 * @param customLayout
	 *            : is name layout
	 * @param position
	 *            : is name position on layout
	 */
	static public Label createLabelPosition(String styleName,
			CustomLayout customLayout, String position, String value) {
		Label component = new Label();
		addLocation(component, styleName, customLayout, position);
		return component;
	}

	static public NativeButton createNativeButtonPosition(String styleName,
			CustomLayout customLayout, String position, String caption) {
		NativeButton component = new NativeButton();
		component.setCaption(caption);
		component.setImmediate(true);
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	static public TextArea createTextAreaPosition(String styleName,
			CustomLayout customLayout, String position) {
		TextArea component = new TextArea();
		component.setNullRepresentation("");
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	/**
	 * Create combobox and load data from database
	 * 
	 * @param styleName
	 *            : Class ccs name
	 * @param customLayout
	 *            : Layout set combobox
	 * @param position
	 *            : Position would set on layout
	 */
	static public Select createComboBoxPosition(String styleName,
			CustomLayout customLayout, String position) {
		Select component = new Select();
		addLocation(component, styleName, customLayout, position);
		return component;
	}

	/**
	 * Create PopupDateField and load data from database
	 * 
	 * @param styleName
	 *            : Class ccs name
	 * @param customLayout
	 *            : Layout set PopupDateField
	 * @param position
	 *            : Position would set on layout
	 */
	static public PopupDateField createPopupDateFieldPosition(String styleName,
			CustomLayout customLayout, String position) {
		PopupDateField component = new PopupDateField();
		component.setInvalidAllowed(false);
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	static public ListSelect createListSelectPosition(String styleName,
			CustomLayout customLayout, String position) {
		ListSelect component = new ListSelect();
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	static public void reloadSelectBoxItems(Select component, String type, List<SystemDetail> values) {
		component.removeAllItems();
		
		if (values != null && values.size() > 0) {
			if (type.equals(TableName.COUNTRY.toString())) {
				addItemsToSelectWithUserSee(component, values);
			} else {
				addItemsToSelect(component, values);
			}
		}
	}

	static public void reloadSelectBoxItems(Select component, String type, String roleName) {
		component.removeAllItems();
		
		ListBoxDataController listBoxDataController = new ListBoxDataController();
		List<ListBoxData> boxDatas = listBoxDataController
				.getSystemValueRefs(type, roleName);
		
		if (boxDatas != null) {
			if (type.equals(TableName.COUNTRY.toString())) {
				addItemsToSelectBoxWithUserSee(component, boxDatas);
			} else {
				addItemsToSelectBox(component, boxDatas);
			}
		} 
	}

	static private void addItemsToSelectWithUserSee(Select component, List<SystemDetail> boxDatas) {
		if (null != SessionData.getCountriesToSee() && !SessionData.getCountriesToSee().isEmpty()) {
			
			for (SystemDetail boxData : boxDatas) {
				for (SystemValue sys : SessionData.getCountriesToSee()) {
					if (boxData.getSystemCode().equals(sys.getSystemCode())) {
						component.addItem(boxData.getSystemCode());  
						component.setItemCaption(boxData.getSystemCode(), boxData.getLabel());						
					}
				}
			}
		} else {
			addItemsToSelect(component, boxDatas);
		}
	}

	static private void addItemsToSelectBoxWithUserSee(Select component, List<ListBoxData> boxDatas) {
		if (null != SessionData.getCountriesToSee() && !SessionData.getCountriesToSee().isEmpty()) {
			
			for (ListBoxData boxData : boxDatas) {
				if (UserCanSee(SessionData.getCountriesToSee(), boxData.getCode())) {
					component.addItem(boxData.getCode());  
					component.setItemCaption(boxData.getCode(), boxData.getName());
				}
			}
		} else {
			addItemsToSelectBox(component, boxDatas);
		}
	}

	static private void addItemsToSelect(Select select, List<SystemDetail> boxDatas) {
		for (SystemDetail boxData : boxDatas) {
			select.addItem(boxData.getSystemCode());  
			select.setItemCaption(boxData.getSystemCode(), boxData.getLabel());
		}
	}
	
	static private void addItemsToSelectBox(Select select, List<ListBoxData> boxDatas) {
		for (ListBoxData boxData : boxDatas) {
			select.addItem(boxData.getCode());  
			select.setItemCaption(boxData.getCode(), boxData.getName());
		}
	}
	
	static private boolean UserCanSee(List<SystemValue> countriesToSee,
			String code) {
		for (SystemValue systemValue : countriesToSee) {
			if (systemValue.getSystemCode().equals(code)) {
				return Boolean.TRUE;
			}
		}
		return Boolean.FALSE;
	}

	static public CheckBox createCheckBox(String caption,
			String styleName, CustomLayout customLayout, String position) {
		CheckBox component = new CheckBox();
		if (caption != null) {
			component.setCaption(caption);
		}
		addLocation(component, styleName, customLayout, position);
		return component;
	}

	static public NumericField createDoubleField(CustomLayout customLayout,
			String styleName, String position) {
		NumericField component = ComponentFactory.createDoubleField();
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	static public NumericField createIntegerField(CustomLayout customLayout,
			String styleName, String position) {
		NumericField component = ComponentFactory.createIntegerField();
		addLocation(component, styleName, customLayout, position);
		return component;
	}
	
	static public String getValueSelect(Select select) {
		String valueSelect = "";
		if (null != select.getValue()) {
			valueSelect = select.getValue().toString();
		}
		return valueSelect;
	}
	
	static public boolean getEnableFromSelect(Select select) {
		boolean enable = Boolean.FALSE;
		if (null != select && null != select.getValue()) {
			enable = Boolean.TRUE;
		}
		return enable;
	}
	
	static public boolean getValueCheckBox(CheckBox checkBox) {
		boolean enable = Boolean.FALSE;
		if (null != checkBox && null != checkBox.getValue()) {
			enable = (boolean)checkBox.getValue();
		}
		return enable;
	}
	
	static public String getValueTextArea(TextArea textArea) {
		return getValueField(textArea);
	}
	
	static public String getValueComboBox(ComboBox comboBox) {
		return getValueField(comboBox);
	}

	static public String getValueTextField(TextField textField) {
		return getValueField(textField);
	}
	
	static public String getValueField(Field field) {
		String value = "";
		if (null != field.getValue()) {
			value = field.getValue().toString();
		}
		return value;
	}
	
	static public void setFieldsEnable(CheckBox checkBox, Field... fields) {
		for (Field field : fields) {
			if (field instanceof Select) {
				setSelectBoxEnable(checkBox, (Select)field);
			} else if (field instanceof TextField) {
				setTextFieldEnable(checkBox, (TextField)field);
			} else if (field instanceof CheckBox) {
				setCheckBoxEnable(checkBox, (CheckBox)field);
			} else if (field instanceof ComboBox) {
				setComboBoxEnable(checkBox, (ComboBox)field);
			}
		}
	}
	
	static public void setCheckBoxEnable(CheckBox checkBox, CheckBox checkBoxNeedEnable) {
		checkBoxNeedEnable.setValue(checkBox.getValue());
	}
	
	static public void setTextFieldEnable(CheckBox checkBox, TextField textField) {
		Boolean enabled = BooleanUtil.getValueWithoutNull((Boolean)checkBox.getValue());
		textField.setEnabled(enabled);
		if (!enabled) {
				textField.setValue("");
		}
	}
	
	static public void setSelectBoxEnable(CheckBox checkBox, Select selectBox) {
		Boolean enabled = BooleanUtil.getValueWithoutNull((Boolean)checkBox.getValue());
		selectBox.setEnabled(enabled);
		if (!enabled) {
				selectBox.setValue(null);
		}
	}
	
	static public void setComboBoxEnable(CheckBox checkBox, ComboBox comboBox) {
		Boolean enabled = BooleanUtil.getValueWithoutNull((Boolean)checkBox.getValue());
		comboBox.setEnabled(enabled);
		if (!enabled) {
				comboBox.setValue(null);
		}
	}
	
	static public void setSelectBoxValue(Select select, String value) {
		select.setValue(null);
		if (!StringUtil.isEmptyOrBlank(value)) {
			select.setValue(value);
		}
	}
	static public void setSelectBoxValue(Select select, PriceType value) {
		select.setValue(null);
		if (null != value) {
			select.setValue(value);
		}
	}
	
	static public BlurListener blurListener = new BlurListener() {
		private static final long serialVersionUID = 6560067584148835127L;

		public void blur(BlurEvent event) {
			TextField source = (NumericField) event.getComponent();
			Integer number = IntegerUtil.parseInteger(source.toString());
			if (number == null){
				 LOG.error("This is not number");
			} 
		}
	};
	
	
}
